﻿using BaseMsg;
using K;
using K.Client;
using Newtonsoft.Json;
using ProtoBuf;
using System;
using System.IO;

public class LuaMsgFactory
{
    static KProtobufSerializer serializer = new KProtobufSerializer();

    public static Msg LuaMsgToMsg(LuaMsg luaMsg)
    {
        var msg = new Msg();
        msg.id = luaMsg.id;

        var head = new MsgHead();
        head.MsgID = luaMsg.head.MsgID;
        head.RoleID = luaMsg.head.RoleID;
        msg.head = head;

        var msMsgBody = new MemoryStream(luaMsg.body);
        if (!MsgFactory.DeserializeBody(msg, msMsgBody))
        {
            return null;
        }
#if DEBUG
        LogMsg(msg, false);
#endif
        return msg;
    }

    public static LuaMsg MsgToLuaMsg(Msg msg)
    {
        var luaMsg = new LuaMsg();
        luaMsg.id = msg.id;
        luaMsg.head = msg.head;
        luaMsg.body = MsgFactory.SerializeBody(msg);
#if DEBUG
        LogMsg(msg, false);
#endif
        return luaMsg;
    }

    public static LuaMsg Create(int msgID, byte[] body, long roleID = 0, long DstConnID = 0)
    {
        var msg = new LuaMsg();
        msg.id = msgID;
        var head = new MsgHead();

        head.MsgID = msgID;
        head.DstID = DstConnID;
        head.RoleID = roleID;
        msg.head = head;
        msg.body = body;
        return msg;
    }

    public static LuaMsg Create(int msgID, IExtensible body, long roleID = 0, long DstConnID = 0)
    {
        var msg = new Msg();
        msg.id = msgID;
        var head = new MsgHead();

        head.MsgID = msgID;
        head.DstID = DstConnID;
        head.RoleID = roleID;
        msg.head = head;
        msg.body = body;
        return MsgToLuaMsg(msg);
    }

    public static LuaMsg Create(int msgID, IExtensible body, MsgHead head)
    {
        var msg = new Msg();
        msg.id = msgID;
        head.MsgID = msgID;
        msg.head = head;
        msg.body = body;
        return MsgToLuaMsg(msg);
    }

    public static byte[] SerializePBMsg<T>(T msg)
    {
        var ms = new MemoryStream();
        serializer.Serialize(ms, msg);
        var re = ms.ToArray();
        return re;
    }

    public static byte[] SerializeHead(LuaMsg msg)
    {
        return SerializePBMsg(msg.head as MsgHead);
    }

    public static bool DeserializeHead(LuaMsg msg, MemoryStream ms)
    {
        msg.head = serializer.Deserialize(ms, null, typeof(MsgHead)) as MsgHead;
        msg.id = (msg.head as MsgHead).MsgID;
        return true;
    }

    //Console打印详细信息
    private static void LogMsg(Msg msg, bool sendOrRecv)
    {
        string msgStr = JsonConvert.SerializeObject(msg, Formatting.Indented);
        Console.WriteLine(string.Format("{0} {1}", sendOrRecv ? "===> " : "<=== ", msgStr));
        string msgLog = string.Format("MsgID: {0}", msg.id);
        
        if (msgLog != "")
        {
            Console.WriteLine(string.Format("[{0}]{1}  {2}", DateTime.Now.ToString(), sendOrRecv ? "===> " : "<=== ", msgLog));
        }
    }

    //todo 可以考虑用反射来序列化和反序列化，这样只需要注册一次
    static Type GetMsgType(int nMsgID)
    {
        switch (nMsgID)
        {
            default:
                return null;
        }
    }
}